package com.ship.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ship.entity.dto.VideoContentDto;
import com.ship.service.VideoService;
import com.ship.util.CRequest;
import com.ship.util.HttpClientUtil;
import com.ship.util.MD5Tools;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jsoup.Jsoup;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLDecoder;
import java.util.*;

/**
 * Created by Luoqb on 2017/6/23.
 */
@Service("videoService")
public class VideoServiceImpl implements VideoService {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Value("${video_cache}")
    private String video_cache;
    @Value("${video_url}")
    private String video_url;

    private String host = "http://127.0.0.1/ckmov/";


    @Override
    public  Map<String,Object> getVideo(String url,String type) throws Exception{
        logger.info("请求url为:{}",url);
        int index = url.indexOf("?");
        if(index>-1) {
            url = url.substring(0, index);
            return parse(url,type);
        }else{
            return parse(url,type);
        }
    }

    @Override
    public Map<String, Object> manyLineParse(String url) throws Exception {
        int index = url.indexOf("?");
        if(index>-1) {
            url = url.substring(0, index);
        }
        String fileNmae = MD5Tools.MD5Encode(url,"utf-8");
        return lineParse(url,0,video_url+"/"+fileNmae,fileNmae);
    }


    private Map<String,Object> lineParse(String url,int up,String filePath,String fileName) throws Exception{
        int ups = up;
        String xx = "http://mt2t.5xlm.com:91/";
        if (ups < 4) {
            Map<String, Object> mapReturn = new HashMap<>();
            List<String> manyLine = parseHtml(url);
            List<String> manyLineList = new ArrayList<>();
            for (String lineUrl : manyLine) {
                manyLineList.add(lineUrl);
//                int index = lineUrl.indexOf("url");
//                String u = lineUrl.substring(index+4, lineUrl.length());
//                int xx = u.indexOf("&");
//                String type = "";
//                if(xx>-1){
//                    type = u.substring(xx+1,u.length()).replace("type=","");
//                }
//                if(type.equals("m3u8")){
//                    manyLineList.add(0,lineUrl);
//                }else{
//                    manyLineList.add(lineUrl);
//                }
            }

            for (String lineUrl : manyLineList) {
                String apiUrl = lineUrl;
                Map<String, String> mapRequest = CRequest.URLRequest(apiUrl);

                mapRequest.put("url",URLDecoder.decode(mapRequest.get("url"),"UTF-8"));
                mapRequest.put("type",mapRequest.get("type"));
                mapRequest.put("from","mt2t.com");
                mapRequest.put("device","");
                mapRequest.put("up",ups+"");


                String fjson = HttpClientUtil.doPost(xx+"ifr/api/",mapRequest);
                //{"url":"http://cache.m.iqiyi.com/jp/tmts/748017100/fee9c4794a1dc615bc42127e0cdacaed/?t=588\u0026sc=1f49a148bf2d39363be898fa1534363a\u0026src=76f90cbd92f94a2e925d83e8ccd22cb7","ext":"ajax_iqiyi","msg":"ok"}
                logger.info(xx + "返回{}", fjson);
                JSONObject jsonObject = JSON.parseObject(fjson);
                String ext = jsonObject.getString("ext");
                String msg = jsonObject.getString("msg");
                if (!msg.equals("ok")) {
                    ups ++;
                    logger.info("up 次数{}", ups);
                    return lineParse(apiUrl, ups,filePath,fileName);
                } else {
                    if (ext.equals("m3u8")){
                        String videoUrl = jsonObject.getString("url");
                        URI uri = new URI(videoUrl);
                        String urlM3u8 = URLDecoder.decode(videoUrl,"UTF-8");
                        String content = "";
                        if(urlM3u8.startsWith("http://")) {
                            int findex = urlM3u8.lastIndexOf("/");
                            String fname = urlM3u8.substring(findex+1,urlM3u8.length());
                            if(fname.equals("index.m3u8")){
                                String temp = HttpClientUtil.sendHttpGet(urlM3u8);
                                int tempIndex = temp.indexOf("/");
                                String tempUrl = temp.substring(tempIndex,temp.length());
                                String m3u8Url = "http://" +uri.getHost()+tempUrl;
                                content = HttpClientUtil.sendHttpGet(m3u8Url.replace("\n",""));
                            }else{
                                content = HttpClientUtil.sendHttpGet(urlM3u8);
                            }
                        }else {
                            content = HttpClientUtil.sendHttpGet("http://vip.mt2t.com/"+urlM3u8);
                        }
                        if (content.length()<500){ //判断字符串长度小于500 换下一个线路
                            continue;
                        }
                        if(StringUtils.isEmpty(content)){
                            ups ++;
                            logger.info("up 次数{}", ups);
                            return lineParse(apiUrl, ups,filePath,fileName);
                        }

                        logger.info("m3u8 地址{} 内容{}",urlM3u8,content);
                        File file = new File(filePath + ".m3u8");
                        FileUtils.writeStringToFile(file.getAbsoluteFile(), content, "utf-8");
                        mapReturn.put("type", "m3u8");
                        mapReturn.put("file_add",  video_cache+"/"+file.getName());
                       // mapReturn.put("parent_url","http://"+uri.getHost());
                        //  HttpClientUtil.close();
                        return mapReturn;
                    }else if(ext.equals("ajax_iqiyi")){
                        String videoUrl = jsonObject.getString("url");
                        URI uri = new URI(videoUrl);
                        String content =  HttpClientUtil.sendHttpGet(videoUrl);
                        String c = content.replace("try{callbackfunction(","");
                        String c2 = c.replace(");}catch(e){};","");
                        c2 = c2.replace("var tvInfoJs=","");
                        JSONObject  obj = JSON.parseObject(c2);
                        JSONObject data = obj.getJSONObject("data");
                        String m3u8tx = data.getString("m3utx");
                        String m3u8 =  HttpClientUtil.sendHttpGet(m3u8tx);
                        logger.info("m3u8 地址{} 内容{}",m3u8tx,content);
                        mapReturn.put("type", "m3u8");
                        File file = new File(filePath + ".m3u8");
                        mapReturn.put("file_add", video_url+"/"+file.getName());
                        //mapReturn.put("parent_url","http://"+uri.getHost());
                        FileUtils.writeStringToFile(file.getAbsoluteFile(), m3u8, "utf-8");
                        //  HttpClientUtil.close();
                        return mapReturn;
                    }else if(ext.equals("mp4")){
                        String m3u8 = createM3u8(jsonObject.getString("url"));
                        File file = new File(filePath + ".m3u8");
                        FileUtils.writeStringToFile(file.getAbsoluteFile(), m3u8, "utf-8");
                        mapReturn.put("type", "mp4");
                        mapReturn.put("file_add", video_cache+"/"+file.getName());
                        return mapReturn;
                    }else if(ext.equals("link")){ //TODO 有问题？
                        String urlM3u8 = "http://wanqian.tv/live/iqy.php?url="+url+"&hd=lg";
                        String content =  HttpClientUtil.sendHttpGet(urlM3u8);
                        if(StringUtils.isEmpty(content)){
                            ups ++;
                            logger.info("up 次数{}", ups);
                            return lineParse(apiUrl, ups,filePath,fileName);
                        }
                        logger.info("link 地址{} 内容{}",urlM3u8,content);
                        FileUtils.writeStringToFile(new File(filePath + ".m3u8"), content, "utf-8");
                        mapReturn.put("type", "m3u8");
                        mapReturn.put("file_add", video_url+"/"+fileName+".m3u8");
                        return mapReturn;
                    } else if (ext.equals("xml")) { //TODO 有问题？
                        String surlParam = jsonObject.getString("url");
                        boolean b = surlParam.startsWith("http://");
                        String content = "";
                        if(b){
                            content = HttpClientUtil.sendHttpGet(surlParam);
                        }else{
                            content = HttpClientUtil.sendHttpGet(xx+surlParam);
                        }
                        if(StringUtils.isEmpty(content)){
                            ups ++;
                            logger.info("up 次数{}", ups);
                            return lineParse(apiUrl, ups,filePath,fileName);
                        }
                        logger.info("xml{}",content);
                        Map<String,Object> msp = parseXml(content);
                        String m3u8 = createM3u8ByMap(msp);
                        File file = new File(filePath + ".m3u8");
                        FileUtils.writeStringToFile(file.getAbsoluteFile(), m3u8, "utf-8");
                        mapReturn.put("type", "m3u8");
                        mapReturn.put("file_add", video_cache+"/"+file.getName());
                        return mapReturn;
                        // HttpClientUtil.close();
                    }else if(ext.equals("m3u8_list")) { //TODO 有问题？
                        url =  URLDecoder.decode(url,"UTF-8");
                        String m3u8 = HttpClientUtil.sendHttpGet("http://vip.mt2t.com/yun/m3u8?url=" + url + "&up=0");
                        if(StringUtils.isEmpty(m3u8)){
                            ups ++;
                            logger.info("up 次数{}", ups);
                            return lineParse(apiUrl, ups,filePath,fileName);
                        }
                        logger.info("hm3u8_list返回{}",m3u8);
                        String msgM3u8 = "";
                        try {
                            JSONObject json = JSONObject.parseObject(m3u8);
                            msgM3u8 = json.getString("msg");
                        }catch (Exception e){
                            msgM3u8 = "1";
                        }
                        // if (msgM3u8.equals("缺少必须参数~!")) {
                        if (!msgM3u8.equals("1")) {
                            ups ++;
                            logger.info("up 次数{}", ups);
                            return lineParse(apiUrl, ups,filePath,fileName);
                        }else {
                            FileUtils.writeStringToFile(new File(filePath + ".m3u8"), m3u8, "utf-8");
                            mapReturn.put("type", "m3u8");
                            mapReturn.put("file_add", video_url+"/"+fileName+".m3u8");
                            //  HttpClientUtil.close();
                            return mapReturn;
                        }
                    }
                }
            }
            return mapReturn;
        }else{
            return null;
        }

    }

    private List<String> parseHtml(String url){
        String htmlUrl = "http://y.mt2t.com/lines?url="+url;
        List<String> list = new ArrayList<>();
        String htmlContent = HttpClientUtil.pickData(htmlUrl);
        org.jsoup.nodes.Document document = Jsoup.parse(htmlContent);
        org.jsoup.nodes.Element element = document.getElementById("opciones");
        Elements a = element.getElementsByTag("a");
        for(org.jsoup.nodes.Element e:a){
            String addr = e.attr("onclick");
            int index = addr.indexOf("'");
            int end = addr.lastIndexOf("'");
            String u = addr.substring(index+1,end);
            list.add(u);
        }
        return list;
    }


    private String parseUrl(String videoUrl,String type){
        if(type.equals("mgtv")){
            String url = videoUrl.replace("m.","www.");
            url = url.replace("#/","");
            url = url+".html";
            logger.info("替换url为:{}",url);
            return url;
        }else if (type.equals("sohu")){
            String url = videoUrl.replace("//m.","//");
            return url;
        }else if (type.equals("qq")){
            String url = videoUrl.replace("//m.","//");
            return url;
        }else if (type.equals("youku")){
            String url = videoUrl.replace("m.","v.");
            url = url.replace("video","v_show");
            return url;
        }else if (type.equals("iqiyi")){
            String url = videoUrl.replace("m.","www.");
            return url;
        }else{
            return videoUrl;
        }
    }

    private Map<String,Object> parse(String videoUrl,String videoType) throws Exception{
        videoUrl = parseUrl(videoUrl,videoType);
        logger.info("请求url:{}",videoUrl);
        String key = MD5Tools.MD5Encode(videoUrl, "UTF-8");
        Map<String,Object> map = new HashMap<>();
        String value = HttpClientUtil.sendHttpGet(host+"index.php?url="+videoUrl);
        JSONObject jsonObject = JSON.parseObject(value.trim());
        String vv = getKey(videoUrl,jsonObject);
        JSONObject content = JSONObject.parseObject(vv.trim());
        String success = content.getString("success");
        String type = content.getString("type");
        if(success.equals("1")) {
            String play = content.getString("play");
            String url2 = content.getString("url");
            if(play.equals("url")){

            }else if(play.equals("ajax")) {
                if (type.equals("qq")) {
                    Map mapParam = CRequest.URLRequest(url2);
                    String u = "http://h5vv.video.qq.com/getinfo?charge=0&vid=" + mapParam.get("vid") + "&defaultfmt=auto&otype=json&guid="+mapParam.get("guid")+"&platform="+mapParam.get("platform")+"&defnpayver=1&appVer=3.0.83&sdtfrom="+mapParam.get("sdtfrom")+"" +
                            "&host=v.qq.com&ehost=https%3A%2F%2Fv.qq.com%2Fx%2Fcover%2Fnuijxf6k13t6z9b%2Fl0023olk3g4.html&_0=" +
                            ""+mapParam.get("_0")+"&defn=mp4&fhdswitch=0&show1080p=1&isHLS=0&newplatform="+mapParam.get("sdtfrom")+"" +
                            "&defsrc=1&_1="+mapParam.get("_1")+"&_2="+mapParam.get("_2");
                    String getInfo = HttpClientUtil.sendHttpGet(u);
                    int pos = "QZOutputJson=".length();
                    String j = getInfo.substring(pos,getInfo.length()-1);
                    logger.info("getInfo:{}",j);
                    JSONObject jsonObject1 = JSONObject.parseObject(j);
                    if(jsonObject1.getString("exem").equals("0")) {
                        JSONObject jo = jsonObject1.getJSONObject("vl");
                        JSONArray jsonArray = jo.getJSONArray("vi");
                        JSONObject vi = (JSONObject)jsonArray.get(0);
                        url2 = "http:"+url2 + "&filename="+vi.getString("lnk")+".mp4";
                        String getKey = HttpClientUtil.sendHttpGet(url2);
                        logger.info("getKey:{}",j);
                        JSONObject ul = vi.getJSONObject("ul");
                        JSONArray ui = ul.getJSONArray("ui");
                        String url = ((JSONObject)ui.get(0)).getString("url");
                       // getinfo.vl.vi[0].ul.ui[0].url + json.filename + '?sdtfrom=' + get.sdtfrom + '&guid=' + get.guid + '&vkey=' + json.key
                        String jsonStr = getKey.substring(pos,getKey.length()-1);
                        JSONObject json = JSON.parseObject(jsonStr);
                        String mp4Url = url +json.get("filename")+"?sdtfrom"+mapParam.get("sdtfrom")+ "&guid=" + mapParam.get("guid") + "&vkey=" + json.get("key");
                        logger.info("mp4Url:{}",mp4Url);
                        String m3u8 = createM3u8(mp4Url);
                        File file = new File(video_url+"/"+ key+ ".m3u8");
                        FileUtils.writeStringToFile(file.getAbsoluteFile(), m3u8, "utf-8");
                        map.put("type", "mp4");
                        map.put("file_add", video_cache+"/"+file.getName());
                    }
                   return map;
                } else if (type.equals("youku")) {
                    return parseM3u8(url2, video_url, key);
                } else if (type.equals("iqiyi")) {
                    String ajax = HttpClientUtil.sendHttpGet(content.getString("url"));
                    int ii = "var tvInfoJs=".length();
                    String j = ajax.substring(ii, ajax.length());
                    JSONObject object = JSONObject.parseObject(j).getJSONObject("data");
                    String url = "";
                    JSONArray vidl = object.getJSONArray("vidl");
                    for (int i = 0; i < vidl.size(); i++) {
                        JSONObject jsonObject1 = (JSONObject) vidl.get(i);
                        url = jsonObject1.getString("m3u");
                        if (StringUtils.isNotEmpty(url)) {
                            break;
                        }
                    }
                    return parseM3u8(url, video_url, key);
                }
            }else if (play.equals("xml")){
                return parseXmlByVideo(url2, video_url, key);
            }
        }
        return  map;
    }

    private String getKey(String url ,JSONObject jsonObject ){
        String time = jsonObject.getString("time");
        String key = jsonObject.getString("key");
        String type = jsonObject.getString("type");
        Map<String,String> map = new HashMap<>();
        map.put("time",time);
        map.put("url", url);
        map.put("key",key);
        map.put("type",type);
        String vv = HttpClientUtil.sendHttpPost(host+"ckmain.php",map);
        return vv;
    }

    private  String  createM3u8(String url){
        StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append("#EXTM3U\n");
            stringBuffer.append("#EXT-X-TARGETDURATION:10\n" );
            stringBuffer.append("#EXT-X-VERSION:3\n" );

                stringBuffer.append("#EXTINF:0,\n");
                stringBuffer.append(url+"\n");
            stringBuffer.append("#EXT-X-ENDLIST\n");
        return stringBuffer.toString();
    }
    private  String  createM3u8ByMap(Map<String,Object> map){
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("#EXTM3U\n");
        stringBuffer.append("#EXT-X-TARGETDURATION:10\n" );
        stringBuffer.append("#EXT-X-VERSION:3\n" );
                List text = (List)map.get("text");
                List seconds = (List)map.get("seconds");
                for (int i = 0; i < seconds.size(); i++) {
                    stringBuffer.append("#EXTINF:" + seconds.get(i) + ",\n");
                    stringBuffer.append(text.get(i)+"\n");
                }
           // stringBuffer.append(url+"\n");

        stringBuffer.append("#EXT-X-ENDLIST\n");
        return stringBuffer.toString();
    }

    private  Map<String,Object>  parseXmlByVideo(String url,String filePath,String fileName){
        Map<String,Object> mapReturn = new HashMap<>();
        String pos = url.substring(url.indexOf("?") , url.length());
        try {
            String xml = HttpClientUtil.sendHttpGet(host+"ckmain.php"+ pos);
            Map<String,Object> map = parseXml(xml);
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append("#EXTM3U\n");
            stringBuffer.append("#EXT-X-TARGETDURATION:"+getMax(map.get("seconds"))+"\n" );
            stringBuffer.append("#EXT-X-VERSION:3\n" );

            List<String> seconds = (List<String>) map.get("seconds");
            List<String> text = (List<String>) map.get("text");
            for(int i=0;i<text.size();i++){
                if (seconds!=null&&seconds.size()>0) {
                    stringBuffer.append("#EXTINF:" + seconds.get(i) + ",\n");
                }else{
                    stringBuffer.append("#EXTINF:0,\n");
                }
                stringBuffer.append(text.get(i)+"\n");
            }
            stringBuffer.append("#EXT-X-ENDLIST\n");
            logger.info("xml路劲:{}",filePath);
            File file = new File(video_url+"/" + fileName+ ".m3u8");
            FileUtils.writeStringToFile(file, stringBuffer.toString(), "utf-8");
            mapReturn.put("type", "m3u8");
            mapReturn.put("file_add", video_cache+"/"+file.getName());
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return mapReturn;
    }

    public static double getMax(Object arr){
        double max = 0;
        if(arr instanceof List){
            List<String> list = (List<String>)arr;
             max = Double.parseDouble(list.get(0));
            for(String str:list){
                double tmp = Double.parseDouble(str);
                if(tmp>max){
                    max=Double.parseDouble(str);
                }
            }
        }
        return max;
    }

    private Map<String,Object>  parseM3u8(String url,String filePath,String fileName){
        Map<String,Object> mapReturn = new HashMap<>();
        try {
            url = URLDecoder.decode(url,"UTF-8");
            String m3u8 = HttpClientUtil.sendHttpGet(new URL( url));
            logger.info("m3u8路劲:{}",filePath);
            File file = new File(filePath+"/" +fileName+ ".m3u8");
            FileUtils.writeStringToFile(file, m3u8, "utf-8");
            mapReturn.put("type", "m3u8");
            mapReturn.put("file_add", video_cache+"/"+file.getName());
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return mapReturn;
    }




    private Map<String,Object> parseXml(String xml){
        String x = xml.replaceAll("\n","");

        Map<String,Object> map = new HashMap<>();
        try {
            String xmlReplace = x.replaceAll("<flashvars>.*</flashvars>","");
            xmlReplace = xmlReplace.replaceAll("<\\?xml version=\"1.0\" encoding=\"utf-8\"\\?>","");
            InputStream in = new ByteArrayInputStream(xmlReplace.getBytes("UTF-8"));
            SAXBuilder sb = new SAXBuilder();
            Document document = sb.build(in);
            Element root = document.getRootElement();
            Element video = root.getChild("video");
            List listVideo = root.getChildren("video");
            if(listVideo.size()==1) {
                List list = video.getChildren("file");
                List size = video.getChildren("size");
                List seconds = video.getChildren("seconds");
                List<String> text = new ArrayList<>();
                List<String> sizeList = new ArrayList<>();
                List<String> secondsList = new ArrayList<>();
                for (int i = 0; i < list.size(); i++) {
                    Element element = (Element) list.get(i);
                    text.add(element.getText());
                    map.put("text", text);
                }
                for (int i = 0; i < size.size(); i++) {
                    Element element = (Element) size.get(i);
                    sizeList.add(element.getText());
                    map.put("size", sizeList);
                }
                for (int i = 0; i < seconds.size(); i++) {
                    Element element = (Element) seconds.get(i);
                    secondsList.add(element.getText());
                    map.put("seconds", secondsList);
                }
                logger.info("xml 解析json {}" + JSONObject.toJSONString(map));
            }else{
                List<String> text = new ArrayList<>();
                List<String> sizeList = new ArrayList<>();
                List<String> secondsList = new ArrayList<>();
                for(int i =0 ;i<listVideo.size();i++){
                    Element element = (Element) listVideo.get(i);
                    Element file = element.getChild("file");
                    text.add(file.getText());
                    map.put("text", text);
                    Element size = element.getChild("size");
                    sizeList.add(size.getText());
                    map.put("size", sizeList);
                    Element seconds = element.getChild("seconds");
                    secondsList.add(seconds.getText());
                    map.put("seconds", secondsList);
                }
            }
        } catch (JDOMException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return map;
    }

}
